import os
import platform
import configparser
import re
import shlex
import subprocess

import chardet
from loguru import logger


def read_md_table(filepath) -> list:
    content = read_file(filepath)
    content_list = content.split('\n')
    table_keys = [i.strip() for i in content_list[0].split('|') if i.strip()]
    result = []
    for table_str in content_list[2:]:
        table_list = [i.strip() for i in table_str.split('|') if i.strip()]
        result.append(dict(zip(table_keys, table_list)))
    return result


def read_file(filepath):
    get_file_encoding(filepath)
    with open(filepath, encoding='utf-8') as f:
        content = f.read()
    return content


class MyParseIni(configparser.ConfigParser):
    def as_dict(self):
        d = dict(self._sections)
        for k in d:
            d[k] = dict(d[k])
        return d


def get_file_encoding(filepath):
    file_encoding = chardet.detect(open(filepath, "rb").read())
    file_encode = file_encoding['encoding']
    logger.info('{} encoding is {}'.format(filepath, file_encode))
    return file_encode


def parse_ini(filepath):
    get_file_encoding(filepath)
    conf = MyParseIni()
    conf.read(filepath, encoding="utf-8")
    return conf.as_dict()


def write_ini(filepath, ini_dict: dict):
    cf = MyParseIni()
    for section, value_dict in ini_dict.items():
        cf.add_section(section)
        for key, value in value_dict.items():
            if isinstance(value, int):
                value = str(value)
            cf.set(section, key, value)
    cf.write(open(filepath, 'w', encoding='utf-8'))
    get_file_encoding(filepath)


def get_role_name(content: str):
    content = content[:20]
    p = re.compile(r'[<](.*?)[>]', re.S)  # 最小匹配
    result = re.findall(p, content)
    if result:
        return result[0]


def add_env_path(path):
    origin_path = os.getenv('PATH')
    seq = ';' if platform.system() == 'Windows' else ':'
    path += seq + origin_path
    os.environ['PATH'] = path


def get_execute_cmd_result(cmd: str, shell=False, **kwargs):
    cmd_err = "execute cmd='{}' failed".format(cmd)
    args = cmd if shell else shlex.split(cmd)
    logger.info("cmd={}, shell={}, args={}".format(cmd, shell, args))
    try:
        res = subprocess.check_output(args, stderr=subprocess.STDOUT, universal_newlines=True,
                                      shell=shell, encoding="utf-8", **kwargs)
    except subprocess.TimeoutExpired:
        err = "{}, timeout={} seconds".format(cmd_err, kwargs.get('timeout'))
        logger.error(err)
        raise Exception(err)
    except subprocess.CalledProcessError as e:
        err = "{}, code={}, err={}".format(cmd_err, e.returncode, e.output.strip())
        logger.error(err)
        raise Exception(err)
    except Exception as e:
        err = "{}, err={}".format(cmd_err, str(e))
        logger.error(err)
        raise Exception(err)
    else:
        msg = "cmd={}, return_code=0".format(cmd)
        logger.debug(msg)
        # return bytes.decode(p).strip()
        return res


if __name__ == '__main__':
    file_path = os.path.join("../setting/role_config.ini")
    res = parse_ini(file_path)
    print(res)
